﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;

#pragma warning disable 1998

namespace CloudStorageLight.WpfClient.Tests
{

    [TestClass]
    public class MainVMTest
    {
        [TestInitialize]
        public void TestSetUp()
        {
            AppViewModel.ExecuteActionAsyncMode = false;
            //SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        }

        class MyBlobDataManager : BlobDataManager
        {
            public int DownloadCount { get; set; }

            public List<TreeItem> Files { get; set; }

            public override async System.Threading.Tasks.Task CopyAsync(string path, string target)
            {
            }

            public override async Task CreateFolderAsync(string path, string newDirectory, bool ensure = false)
            {
            }

            public override async Task DeleteAsync(string path)
            {
            }

            public override async Task<DownloadInfo> DownloadAsync(string path, string localPath, string snapshot = null, string mode = null, IProgress<double> progress = null, long totalSize = 0)
            {
                DownloadCount++;
                return null;
            }

            public override async Task<DownloadInfo> DownloadAsync(string path, System.IO.Stream target, string snapshot = null, string mode = null, IProgress<double> progress = null, long totalSize = 0)
            {
                DownloadCount++;
                return null;
            }


            public override async Task<TreeItem> GetFileAsync(string path)
            {
                return path.EndsWith("/") ? (TreeItem)new DirectoryItem { Path = path } : (TreeItem)new FileItem { Path = path };
            }

            public override async Task<System.Collections.Generic.List<TreeItem>> GetFilesAsync(string path, int start, int size = MaxFilesSize)
            {
                return Files ?? new System.Collections.Generic.List<TreeItem>();
            }

            public override async Task<bool> LoginAsync(string service, string mail, string pass, bool a, bool b)
            {
                return true;
            }

            public override async Task RenameAsync(string path, string target)
            {
            }

            public override async Task<System.Collections.Generic.List<TreeItem>> SearchFilesAsync(string path, string query, int start, int size)
            {
                return new System.Collections.Generic.List<TreeItem>();
            }

            public override async Task<UploadInfo> UploadFileAsync(string path, string filename, IProgress<double> progress =  null)
            {
                return new UploadInfo() { UploadedPath = path + System.IO.Path.GetFileName(filename) };
            }
            public override async Task MoveAsync(string path, string target)
            {
            }
        }


        [TestMethod]
        public void MainVMコンストラクタ()
        {
            var vm = new MainVM();
        }

        [TestMethod]
        public void CopyCommandTest()
        {
            MainVM vm = CreateViewModel();
            DirectoryItem f3 = vm.Folders[0].Folders[2];
            var data = new FileCommandArg();
            data.Path = "/F3/";
            data.Files = new string[]{"/F1/T1.txt", "/F1/T3.txt"};
            vm.CopyCommand.Execute(data);

            Assert.AreEqual(2, f3.Files.Count);
        }

        [TestMethod]
        public void MoveCommandTest()
        {
            MainVM vm = CreateViewModel();
            DirectoryItem f1 = vm.Folders[0].Folders[0];
            DirectoryItem f3 = vm.Folders[0].Folders[2];
            var data = new FileCommandArg();
            data.Path = "/F3/";
            data.Files = new string[] { "/F1/T1.txt", "/F1/T3.txt" };
            vm.MoveCommand.Execute(data);

            Assert.AreEqual(1, f1.Files.Count);
            Assert.AreEqual(2, f3.Files.Count);
        }

        [TestMethod]
        public void DeleteFileCommandTest()
        {
            MainVM vm = CreateViewModel();
            DirectoryItem f1 = vm.Folders[0].Folders[0];
            DirectoryItem f3 = vm.Folders[0].Folders[2];
            var data = new FileCommandArg();
            data.Files = new string[] { "/F1/T1.txt", "/F1/T3.txt" };
            vm.DeleteFileCommand.Execute(data);

            Assert.AreEqual(1, f1.Files.Count);
        }

        [TestMethod]
        public void DeleteFileCommandDirectoryTest()
        {
            MainVM vm = CreateViewModel();
            DirectoryItem f2 = vm.Folders[0].Folders[1];
            var data = new FileCommandArg();
            data.Files = new string[] { "/F2/F2/" };
            vm.DeleteFileCommand.Execute(data);

            Assert.AreEqual(1, f2.Folders.Count);
        }

        [TestMethod]
        public void DownloadFolderCommandTest()
        {
            var mng = new MyBlobDataManager();
            mng.Files = new List<TreeItem>();
            mng.Files.Add(new FileItem() { Path = "/F2/T1.txt" , AttachmentFileName = "T1.txt"});
            MainVM vm = CreateViewModel(mng);
            DirectoryItem f2 = vm.Folders[0].Folders[1];
            var data = new FileCommandArg();
            vm.DownloadFolderCommand.Execute("/F2/");

            Assert.AreEqual(1, mng.DownloadCount);
        }

        [TestMethod]
        public void UploadCommandTest()
        {
            System.IO.File.WriteAllText("a.txt", "");
            System.IO.File.WriteAllText("b.txt", "");
            MainVM vm = CreateViewModel();
            DirectoryItem f3 = vm.Folders[0].Folders[2];
            var data = new FileCommandArg();
            data.Path = "/F3/";
            data.Files = new string[] { "a.txt","b.txt"  };
            vm.UploadCommand.Execute(data);

            Assert.AreEqual(2, f3.Files.Count);
        }

        [TestMethod]
        public void SelectedItemChangedCommandTest()
        {
            MainVM vm = CreateViewModel();
            DirectoryItem f1 = vm.Folders[0].Folders[0];
            vm.SelectedItemChangedCommand.Execute(f1);

            Assert.AreEqual("/F1/", vm.SelectedFolder.Path);
        }

        class MyMainVM: MainVM
        {
            public bool ReturnValueAsShowYesNo = true;

            protected override string ShowFolderDailog()
            {
                return System.IO.Path.GetTempPath();
            }

            protected override bool ShowYesNo(string message, string title = "confirm")
            {
                return ReturnValueAsShowYesNo;
            }

        }

        private static MainVM CreateViewModel(BlobDataManager mng = null)
        {
            var vm = new MyMainVM();
            BlobDataManager.Instance = mng ?? new MyBlobDataManager();
            vm.Init();
            var root = vm.Folders[0];
            var f1 = new DirectoryItem() { Path = "/F1/" };
            f1.Folders.Clear();
            root.Folders.Add(f1);
            f1.Files.Add(new FileItem { Path = "/F1/T1.txt" });
            f1.Files.Add(new FileItem { Path = "/F1/T2.txt" });
            f1.Files.Add(new FileItem { Path = "/F1/T3.txt" });
            vm.Folders.Add(f1);
            var f2 = new DirectoryItem() { Path = "/F2/" };
            f2.Folders.Clear();
            root.Folders.Add(f2);
            var f21 = new DirectoryItem() { Path = "/F2/F1/" };
            f2.Folders.Add(f21);
            var f22 = new DirectoryItem() { Path = "/F2/F2/" };
            f2.Folders.Add(f22);
            f22.Files.Add(new FileItem { Path = "/F2/F2/T1.txt" });

            vm.Folders.Add(f2);
            var f3 = new DirectoryItem() { Path = "/F3/" };
            f3.Folders.Clear();
            root.Folders.Add(f3);
            vm.Folders.Add(f3);

            return vm;
        }
    }
}
